from datetime import datetime
import re
from typing import Optional
from fastapi import FastAPI, Request, Response
from pydantic import BaseModel
from urllib.parse import quote
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
import receive
import reply
from excel_db import excel_db

app = FastAPI(docs_url=None, redoc_url=None)
db = excel_db()

# 设置模板文件夹路径
template_dir = "html/"
templates = Jinja2Templates(directory=template_dir)
app.mount("/static", StaticFiles(directory="html/static/"), name="static")


class Item(BaseModel):
    index: Optional[int] = None
    address: str
    name: str
    date: datetime
    phone_num: str
    rent: str
    rent_status: str
    note: str


class HousingForm(BaseModel):
    address: str
    room_num: int


@app.get("/hello/{name}")
async def say_hello(name: str):
    return {"message": f"Hello {name}"}


# 微信公众号平台对接时使用
@app.get("/wx")
async def access_wx(echostr: int):
    return echostr


@app.post("/wx")
async def message_reply(request: Request):
    xml_data = await request.body()
    recMsg = receive.parse_xml(xml_data)
    if isinstance(recMsg, receive.TextMsg) and recMsg.MsgType == 'text':
        response = text_process(recMsg)
        return response

    # elif isinstance(recMsg, receive.EventMsg):
    #     response = event_process(recMsg)
    #     return response
    else:
        print("暂且不处理")
        return "success"


# 收租
@app.get("/wx/rent")
async def rent_collect(index: int):
    if db.update_db(index):
        row = db.select_index(index)
        address = row[7]
        name = row[0]
        day = row[2]
        rent = row[5]
        content = f"<p style=\"font-size: 80px;\">{address} {name} {day}号房租已收</p>"
        date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        log = f"{date}'      '{address} {name} {day}号房租已收, 应收租金{rent}元"
        with open('resource/rent_log.txt', 'a') as f:
            f.write(log + '\n')
    else:
        content = "<p style=\"font-size: 80px;\">更新失败，请稍后重试</p>"
    response = Response(content, media_type="text/html")
    return response


# 退租
@app.get("/wx/release")
async def rent_release(index):
    if db.delete_db(index):
        row = db.select_index(index)
        address = row[7]
        name = row[0]
        content = f"<p style=\"font-size: 80px;\">{address} {name} 已退房</p>"
    else:
        content = "<p style=\"font-size: 80px;\">更新失败，联系管理员排查问题</p>"
    response = Response(content, media_type="text/html")
    return response


# 新增房源
@app.post("/wx/new")
async def rent_new(house_form: HousingForm):
    address = house_form.address
    room_num = house_form.room_num
    if db.new_db(address, room_num):
        # content = f"<p style=\"font-size: 80px;\">已添加 {address} {room_num} 间房！</p>"
        result = {'result': 1, 'address': address, 'room_num': room_num}
    else:
        # content = "<p style=\"font-size: 80px;\">更新失败，请联系管理员排查问题</p>"
        result = {'result': 2}
    # response = Response(content, media_type="text/html")
    return result


# 新增入住
@app.post("/wx/add")
async def tenant_add(item: Item):
    if not db.exist_address(item.address):
        result = {'result': 4, 'description': '没有该房屋, 请重新输入'}
    else:
        status = db.add_db(item)
        if status == 1:
            # content = f"<p style=\"font-size: 80px;\">已添加 {item.address} 租客 {item.name}！</p>"
            result = {'result': 1}
        elif status == 3:
            # content = f"<p style=\"font-size: 80px;\">{item.address} 房间已满，请先退租！</p>"
            result = {'result': 3, 'description': '房间已满，需要先退租!'}
        else:
            # content = "<p style=\"font-size: 80px;\">更新失败，请联系管理员排查问题</p>"
            result = {'result': 2}
        # response = Response(content, media_type="text/html")
    return result

# 筛选过滤
@app.get("/wx/filter")
async def filter(rContent: str,):

    data = None
    if re.search(r"^[0-3]?\d$", rContent) is not None:
        data = db.select_day(day=int(rContent), remove_yizu=False)
    elif re.search(r"^\d{4}|\d*-\d*$", rContent) is not None:
        data = db.select_address(rContent)
    elif re.search(r"\w+", rContent) is not None:
        data = db.select_name(rContent)
    else:
        # data = db.select_all(remove_empty_lines=False)
        data = db.select_free()

    if not data:
        content = "未查到数据"
    else:
        content = []
        for row in data:
            # 有些没有加好的数字被excel定义为int类型，需要转换一下
            address = str(row[7])
            name = row[0]
            price = str(row[4])
            index = row[8]
            status = row[6]
            phone = str(row[3])
            if row[1] is not None:
                date = row[1].strftime("%Y-%m-%d")
            else:
                date = row[1]
            if row[5] is None:
                note = ""
            else:
                note = row[5]
            r_row = {
                "index": index,
                "address": address,
                "name": name,
                "date": date,
                "price": price,
                "status": status,
                "phone": phone,
                "note": note
             }
            content.append(r_row)
    return content

# 修改数据，直接删除重新添加
@app.post("/wx/modify")
async def tenant_modify(item: Item):
    if not db.exist_address(item.address):
        result = {'result': 4, 'description': '没有该房屋, 请重新输入'}
    else:
        row = db.select_index(item.index)
        if db.delete_db(item.index):
            if db.add_db(item):
                result = {'result': 1}
            else:
                result = {'result': 2, 'description': '添加失败'}
        else:
            result = {'result': 3, 'description': '删除失败'}

    return result


# 批量重置收租状态接口
@app.get("/wx/rent_reset")
async def rent_reset(rContent: str,):
    if rContent == "重置 1-15号":
        if db.reset_db(15):
            content = "1-15号房租已重置为未收租"
            code = 1
        else:
            content = "重置失败，请联系管理员处理"
            code = 0
    else:
        if db.reset_db(16):
            content = "16-31号房租已重置为未收租"
            code = 1
        else:
            content = "重置失败，请联系管理员处理"
            code = 0

    result = {'code': code, 'result': content}
    return result


# 批量重置收租状态接口
@app.get("/wx/rent_count")
async def rent_reset():
    data = db.select_all(remove_empty_lines=True)
    total_room = len(data)
    free_room = 0
    for row in data:
        if row[0] is None:
            free_room += 1
    total_house = len(list(set([x[7] for x in data])))
    content = f"<pre>房屋总数：<b>{total_house}</b>  房间总数：<b>{total_room}</b>  在租：<b>{free_room}</b>  已出租：<b>{total_room - free_room}</b></pre>"
    result = {'code': 1, 'result': content}
    return result

def text_process(recMsg):
    toUser = recMsg.FromUserName
    fromUser = recMsg.ToUserName
    rContent = recMsg.Content.decode('utf-8')
    content = ""
    if re.search(r"^[0-3]?\d$", rContent) is not None:
        day = re.search(r"[0-3]?\d", rContent).group()
        # 先判断该日期有没有租客
        if not db.select_day(day=int(day), remove_yizu=False):
            content = "该日期没有租客"
        else:
            data = db.select_day(day=int(day))
            # 然后查询该日期未收租的租客，如果没有未收租，则回复所有房租已收
            if not data:
                content = "该日期所有房租已收"
            else:
                for row in data:
                    # 有些没有加好的数字被excel定义为int类型，需要转换一下
                    address = str(row[7]) + " " * (7 - len(str(row[7]))) * 2  # 一个数字字符宽度等于两个半角空格
                    name = row[0] + "\u3000" * (3 - len(row[0]))  # 一个汉字宽度等于一个全角空格
                    price = str(row[4]) + " " * (9 - len(str(row[4])))
                    index = row[8]
                    content = content + f"{address}  {name}  {price}  " \
                                        f"<a href=\"http://a.efrey.top/wx/rent?index={index}\">收租</a>  <a href=\"http://a.efrey.top/wx/release_check?index={index}\">退租</a>\n"
    elif re.search(r"统计", rContent) is not None:
        data = db.select_all(remove_empty_lines=True)
        total_room = len(data)
        free_room = 0
        for row in data:
            if row[0] is None:
                free_room += 1
        total_house = len(list(set([x[7] for x in data])))
        content = f"目前共拥有房屋总数：{total_house} \n房间总数：{total_room} \n在租房间：{free_room} \n已出租房间：{total_room - free_room}"
    elif re.search(r"^\d{4}|\d*-\d*$", rContent) is not None:
        data = db.select_address(rContent)
        if not data:
            content = "该房间目前没有租客"
        else:
            for row in data:
                # 有些没有加好的数字被excel定义为int类型，需要转换一下
                address = str(row[7]) + " " * (7 - len(str(row[7]))) * 2  # 一个数字字符宽度等于两个半角空格
                name = row[0] + "\u3000" * (3 - len(row[0]))  # 一个汉字宽度等于一个全角空格
                price = str(row[4]) + " " * (9 - len(str(row[4])))
                index = row[8]
                content = content + f"{address}  {name}  {price} " \
                                    f"<a href=\"http://a.efrey.top/wx/release_check?index={index}\">退租</a>\n"
    elif re.search(r"添加房源", rContent) is not None:
        content = "http://a.efrey.top/wx/new_house.html"
    elif re.search(r"新增入住", rContent) is not None:
        content = "http://a.efrey.top/wx/add_tenant.html"
        # content = "http://a.efrey.top/wx/test.html"
    elif re.search(r"主页", rContent) is not None:
        content = "http://a.efrey.top/wx/main_1007.html"
    elif re.search(r"重置1-15号", rContent) is not None:
        if db.reset_db(15):
            content = "1-15号房租已重置为未收租"
    elif re.search(r"重置16-31号", rContent) is not None:
        if db.reset_db(16):
            content = "16-31号房租已重置为未收租"
    elif re.search(r"最近三天|最近3天", rContent) is not None:
        day = datetime.day

    replyMsg = reply.TextMsg(toUser, fromUser, content.rstrip("\n"))  # 去除最后一个换行符
    response = Response(content=replyMsg.send(), media_type="application/xml")
    return response


# def event_process(recMsg):
#     toUser = recMsg.FromUserName
#     fromUser = recMsg.ToUserName
#     eventKey = recMsg.eventKey
#     if eventKey == 'statistics':
#         data = db.select_all(remove_empty_lines=True)
#         total_room = len(data)
#         free_room = 0
#         for row in data:
#             if row[0] is None:
#                 free_room += 1
#         total_house = len(list(set([x[7] for x in data])))
#         content = f"目前共拥有房屋总数：{total_house} \n房间总数：{total_room} \n在租房间：{free_room} \n已出租房间：{total_room - free_room}"
#     replyMsg = reply.TextMsg(toUser, fromUser, content.rstrip("\n"))  # 去除最后一个换行符
#     response = Response(content=replyMsg.send(), media_type="application/xml")
#     return response


# 新增房源页面
@app.get("/wx/new_house.html")
async def new_house(request: Request):
    return templates.TemplateResponse("new_house.html", {"request": request})


# 新增租客页面
@app.get("/wx/add_tenant.html")
async def new_house(request: Request):
    return templates.TemplateResponse("add_tenant.html", {"request": request})


# 测试页面
@app.get("/wx/main_1007.html")
async def new_house(request: Request):
    return templates.TemplateResponse("main_1007.html", {"request": request})

# 操作成功响应页面
@app.get("/wx/success.html")
async def success(request: Request):
    return templates.TemplateResponse("success.html", {"request": request})


# 操作失败响应页面
@app.get("/wx/fail.html")
async def success(request: Request):
    return templates.TemplateResponse("fail.html", {"request": request})

# 退房增加前置确认页面
@app.get("/wx/release_check")
async def release_check(address: str, name: str, day: int, price: str, request: Request):
    price = quote(price)
    return templates.TemplateResponse("release_check.html", {"request": request, "url": f"http://a.efrey.top/wx/release?address={address}"
                                                                    f"&name={name}&day={day}&price={price}"})


# 修改数据
@app.get("/wx/tenant_modify.html")
async def tenant_modify(index, request: Request):

    row = db.select_index(index)
    return templates.TemplateResponse("modify_tenant.html", {"request": request, "index": index, "name": row[0], "date": row[1],
                                                             "phone": row[3], "price": row[4], "note": row[5], "rent_status": row[6], "address": row[7]})


